package com.coffee.admin.service.platform.impl;

import com.alibaba.fastjson.JSONObject;
import com.coffee.admin.api.common.service.RedisService;
import com.coffee.admin.api.common.service.SmsCodeService;
import com.coffee.admin.api.login.request.LoginByPasswordRequert;
import com.coffee.admin.api.login.request.LoginBySmsRequert;
import com.coffee.admin.api.login.request.LoginRecordReq;
import com.coffee.admin.api.platform.req.PlatformAccountUpdateReq;
import com.coffee.admin.api.platform.result.PlatformResult;
import com.coffee.admin.api.platform.service.PlatformLoginService;
import com.coffee.admin.api.platform.service.PlatformService;
import com.coffee.admin.api.supplier.query.SupplierQuery;
import com.coffee.admin.api.supplier.req.SupplierForgetPasswordReq;
import com.coffee.admin.api.supplier.req.SupplierUpdatePasswordReq;
import com.coffee.admin.api.supplier.result.SupplierResult;
import com.coffee.admin.api.supplier.service.SupplierService;
import com.coffee.admin.service.platform.bean.Platform;
import com.coffee.admin.service.platform.dao.PlatformDao;
import com.coffee.admin.service.supplier.bean.Supplier;
import com.coffee.admin.service.supplier.dao.SupplierDao;
import com.coffee.core.constant.Status;
import com.coffee.core.entity.LoginUser;
import com.coffee.core.enums.ExceptionEnum;
import com.coffee.core.enums.SmsSourceEnum;
import com.coffee.core.exception.BusinessException;
import com.coffee.core.exception.ValidateBusinessException;
import com.coffee.core.util.BeanUtils;
import com.coffee.core.util.PasswordUtil;
import com.coffee.core.util.RegexUtils;
import com.coffee.core.util.UUIDUtils;
import org.apache.dubbo.config.annotation.DubboReference;
import org.apache.dubbo.config.annotation.DubboService;
import org.springframework.beans.factory.annotation.Autowired;

@DubboService(dynamic = true)
public class PlatformLoginServiceImpl implements PlatformLoginService {

    @DubboReference
    private PlatformService platformService;
    @DubboReference
    private RedisService redisService;
    @DubboReference
    private SmsCodeService smsCodeService;
    @DubboReference
    private SupplierService supplierService;
    @Autowired
    private SupplierDao supplierDao;
    @Autowired
    private PlatformDao platformDao;


    public void checkMobile(String mobile) throws BusinessException {
        ValidateBusinessException.assertStringNotBlank(mobile, ExceptionEnum.ERROR_1201);
        boolean isMobile = RegexUtils.checkMobile(mobile);
        ValidateBusinessException.assertTrue(isMobile, ExceptionEnum.ERROR_1218);
    }

    @Override
    public String passwordLogin(LoginByPasswordRequert req) throws BusinessException {
        //手机号码校验
        String mobile = req.getMobile();
        this.checkMobile(mobile);

        //密码校验
        String password = req.getPassword();
        ValidateBusinessException.assertStringNotBlank(password, ExceptionEnum.ERROR_1202);
        PlatformResult result = new PlatformResult();
        result.setMobile(req.getMobile());
        PlatformResult platform = this.platformService.getPlatformService(result);
        SupplierQuery supplierQuery = new SupplierQuery();
        supplierQuery.setMobile(req.getMobile());
        SupplierResult supplier = supplierService.getSupplierResult(supplierQuery);
        if (platform == null && supplier == null) {
            throw BusinessException.build(ExceptionEnum.ERROR_1233);
        }
        if (platform != null) {
            if (!PasswordUtil.checkPass(req.getPassword(), platform.getPassword())) {
                throw BusinessException.build(ExceptionEnum.ERROR_1203);
            }
        }
        if (supplier != null) {
            if (!PasswordUtil.checkPass(req.getPassword(), supplier.getPassword())) {
                throw BusinessException.build(ExceptionEnum.ERROR_1203);
            }
        }
        //保存用户信息到redis中
        String token = setLoginUser(platform, supplier);
        return token;
    }

    @Override
    public String smsLogin(LoginBySmsRequert req) throws BusinessException {
        //手机号码校验
        String mobile = req.getMobile();
        this.checkMobile(mobile);


        PlatformResult result = new PlatformResult();
        result.setMobile(req.getMobile());
        PlatformResult platform = this.platformService.getPlatformService(result);
        SupplierQuery supplierQuery = new SupplierQuery();
        supplierQuery.setMobile(req.getMobile());
        SupplierResult supplier = supplierService.getSupplierResult(supplierQuery);
        if (platform == null && supplier == null) {
            throw BusinessException.build(ExceptionEnum.ERROR_1233);
        }
        //校验验证码
        String smsCode = req.getSmsCode();
        boolean isValid = smsCodeService.validateSmsCode(mobile, smsCode, SmsSourceEnum.BACKSTAGE_LOGIN);
        if (!isValid) {
            throw BusinessException.build(ExceptionEnum.ERROR_1210);
        }
        //登录
        String token = setLoginUser(platform, supplier);
        return token;
    }

    @Override
    public String forgetPassword(SupplierForgetPasswordReq req) throws BusinessException {
        //手机号码校验
        String mobile = req.getMobile();
        this.checkMobile(mobile);
        PlatformResult result = new PlatformResult();
        result.setMobile(req.getMobile());
        PlatformResult platform = this.platformService.getPlatformService(result);

        SupplierQuery param = new SupplierQuery();
        param.setMobile(req.getMobile());
        SupplierResult supplierResult = supplierService.getSupplierResult(param);

        if (supplierResult == null) {
            throw BusinessException.build(ExceptionEnum.ERROR_1233);
        }
        //校验验证码
        String smsCode = req.getSmsCode();
        boolean isValid = smsCodeService.validateSmsCode(mobile, smsCode, SmsSourceEnum.BACKSTAGE_FORGOTPASSWORD);
        if (!isValid) {
            throw BusinessException.build(ExceptionEnum.ERROR_1210);
        }
        SupplierUpdatePasswordReq supplierUpdatePasswordReq = new SupplierUpdatePasswordReq();
        supplierUpdatePasswordReq.setId(supplierResult.getId());
        supplierUpdatePasswordReq.setNewPassword(req.getNewPassword());
        supplierService.updatePassword(supplierUpdatePasswordReq);

        PlatformAccountUpdateReq platformAccountUpdateReq = new PlatformAccountUpdateReq();
        supplierUpdatePasswordReq.setId(supplierResult.getId());
        supplierUpdatePasswordReq.setNewPassword(req.getNewPassword());
        platformService.updatePlatformOperate(platformAccountUpdateReq);
        //登录
        String token = setLoginUser(platform, supplierResult);
        return token;
    }

    private String setLoginUser(PlatformResult platformResult, SupplierResult supplier) throws BusinessException {
        String token = "ps-" + UUIDUtils.getUUID();
        LoginUser userBo = new LoginUser();
        if (platformResult != null && "Y".equals(platformResult.getIsEnable())) {
            userBo.setPlatformUserId(platformResult.getId());
            userBo.setPlatformIsAdmin(platformResult.getIsAdmin());
            Integer platformResultFirstPid = getPlatformResultFirstPid(platformResult);
            userBo.setPlatformId(platformResultFirstPid);
        }
        if (supplier != null && "Y".equals(supplier.getIsEnable())) {
            userBo.setSupplierUserId(supplier.getId());
            userBo.setSupplierIsAdmin(supplier.getIsAdmin());
            Integer firstPid = getFirstPid(supplier);
            userBo.setSupplierId(firstPid);
        }
        if (userBo.getSupplierUserId()==null&&userBo.getPlatformUserId()==null){
            throw new BusinessException(ExceptionEnum.ERROR_1107.getCode(),ExceptionEnum.ERROR_1107.getMessage());
        }

        redisService.set(token, JSONObject.toJSONString(userBo), Status.ExpireEnum.EXPIRED_TOKEN_7);
        return token;
    }

    Integer getFirstPid(SupplierResult supplierResult) {
        if (supplierResult.getPid() == 0) {
            Integer id = supplierResult.getId();
            return id;
        } else {
            SupplierResult supplierResult1 = new SupplierResult();
            Supplier supplier = supplierDao.findById(supplierResult.getPid());
            if (supplier == null) {
                return null;
            }
            BeanUtils.copyProperties(supplierResult1, supplier);
            return getFirstPid(supplierResult1);
        }

    }

    Integer getPlatformResultFirstPid(PlatformResult platformResult) {
        if (platformResult.getPid() == 0) {
            Integer id = platformResult.getId();
            return id;
        } else {
            PlatformResult platformResult1 = new PlatformResult();
            Platform platform = platformDao.findById(platformResult.getPid());
            if (platform == null) {
                return null;
            }
            BeanUtils.copyProperties(platformResult1, platform);
            return getPlatformResultFirstPid(platformResult1);
        }

    }
}
